import { NextRequest, NextResponse } from 'next/server'
import { writeFile, mkdir, readdir } from 'fs/promises'
import { join } from 'path'
import { randomUUID } from 'crypto'
import yauzl from 'yauzl'
import { PrismaClient } from '@prisma/client'
import { requireAdmin, withErrorHandling } from '@/lib/auth-middleware'

const prisma = new PrismaClient()

// 分类映射
const categoryMap = {
  '1': { name: '开发工具', icon: '💻' },
  '2': { name: '设计工具', icon: '🎨' },
  '3': { name: '效率工具', icon: '⚡' },
  '4': { name: '娱乐游戏', icon: '🎮' },
  '5': { name: '学习教育', icon: '📚' },
  '6': { name: '生活服务', icon: '🏠' }
}

function getCategoryName(categoryId: string): string {
  return categoryMap[categoryId as keyof typeof categoryMap]?.name || '其他'
}

function getCategoryIcon(categoryId: string): string {
  return categoryMap[categoryId as keyof typeof categoryMap]?.icon || '📦'
}

export const POST = withErrorHandling(async (request: NextRequest) => {
  return requireAdmin(request, async (req) => {
    const formData = await req.formData()
    const file = formData.get('file') as File
    const title = formData.get('title') as string
    const description = formData.get('description') as string
    const categoryId = formData.get('categoryId') as string

    if (!file || !title || !description || !categoryId) {
      return NextResponse.json(
        { error: '缺少必要参数' },
        { status: 400 }
      )
    }

    // 验证文件类型
    if (!file.name.endsWith('.zip')) {
      return NextResponse.json(
        { error: '只支持ZIP格式文件' },
        { status: 400 }
      )
    }

    // 验证文件大小 (50MB)
    if (file.size > 50 * 1024 * 1024) {
      return NextResponse.json(
        { error: '文件大小不能超过50MB' },
        { status: 400 }
      )
    }

    // 生成唯一的工具ID和部署路径
    const toolId = randomUUID()
    const deployPath = `/deployed-tools/${toolId}`
    const deployDir = join(process.cwd(), 'public', 'deployed-tools', toolId)

    try {

      // 创建部署目录
      await mkdir(deployDir, { recursive: true })

      // 保存上传的文件
      const bytes = await file.arrayBuffer()
      const buffer = Buffer.from(bytes)
      const tempZipPath = join(deployDir, 'temp.zip')
      await writeFile(tempZipPath, buffer)

      // 解压ZIP文件
      await extractZip(tempZipPath, deployDir)

      // 删除临时ZIP文件
      await import('fs').then(fs => {
        if (fs.existsSync(tempZipPath)) {
          fs.unlinkSync(tempZipPath)
        }
      })

      // 验证解压后的文件
      const files = await readdir(deployDir)
      if (files.length === 0) {
        throw new Error('ZIP文件为空或解压失败')
      }

      // 查找入口文件
      let entryFile = 'index.html'
      const htmlFiles = files.filter(f => f.endsWith('.html'))
      if (htmlFiles.length > 0) {
        entryFile = htmlFiles[0]
      }

      // 创建工具数据到数据库
      const toolData = await prisma.tool.create({
        data: {
          id: toolId,
          title,
          description,
          url: deployPath, // 不包含具体文件名，由路由处理
          image: '',
          originalFile: file.name,
          categoryId,
          userId: req.user!.id, // 使用当前认证用户的ID
          status: 'APPROVED',
          isDeployed: true
        },
        include: {
          user: {
            select: { id: true, name: true, email: true }
          },
          category: true
        }
      })

      return NextResponse.json({
        success: true,
        data: toolData,
        message: '工具上传并部署成功'
      })

    } catch (error) {
      console.error('上传失败:', error)

      // 清理失败的部署
      try {
        await import('fs').then(fs => {
          if (fs.existsSync(deployDir)) {
            fs.rmSync(deployDir, { recursive: true, force: true })
          }
        })
      } catch (cleanupError) {
        console.error('清理失败:', cleanupError)
      }

      return NextResponse.json(
        { error: '部署失败，请重试' },
        { status: 500 }
      )
    }
  })
})

// 解压ZIP文件
async function extractZip(zipPath: string, extractDir: string): Promise<void> {
  return new Promise((resolve, reject) => {
    yauzl.open(zipPath, { lazyEntries: true }, (err, zipfile) => {
      if (err) {
        reject(err)
        return
      }

      if (!zipfile) {
        reject(new Error('无法打开ZIP文件'))
        return
      }

      zipfile.readEntry()

      zipfile.on('entry', (entry) => {
        if (/\/$/.test(entry.fileName)) {
          // 目录
          const dirPath = join(extractDir, entry.fileName)
          mkdir(dirPath, { recursive: true }).then(() => {
            zipfile.readEntry()
          }).catch(reject)
        } else {
          // 文件
          zipfile.openReadStream(entry, (err, readStream) => {
            if (err) {
              reject(err)
              return
            }

            if (!readStream) {
              reject(new Error('无法读取文件流'))
              return
            }

            const filePath = join(extractDir, entry.fileName)
            const fileDir = join(filePath, '..')

            mkdir(fileDir, { recursive: true }).then(() => {
              const writeStream = require('fs').createWriteStream(filePath)
              readStream.pipe(writeStream)

              writeStream.on('close', () => {
                zipfile.readEntry()
              })

              writeStream.on('error', reject)
            }).catch(reject)
          })
        }
      })

      zipfile.on('end', () => {
        resolve()
      })

      zipfile.on('error', reject)
    })
  })
}
